package com.yuyue.springFramework.note12;

import com.yuyue.springFramework.note12.entity.cache.CacheA;
import com.yuyue.springFramework.note12.entity.cache.CacheB;
import com.yuyue.springFramework.note12.entity.cache.CacheConfig;
import org.junit.Test;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * 《Spring-12 循环依赖》文章代码
 *  文章地址：https://mp.weixin.qq.com/s/2WFYQTOrYCJufny1QC5Dpg
 */
public class Note12Test {
    @Test
    //构造器循环依赖，无法解决
    public void fun1(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("ApplicationContext04.xml");
        applicationContext.getBean("classForConstructA");
    }

    @Test
    //属性值循环依赖，不受影响
    public void fun2(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("ApplicationContext04.xml");
        applicationContext.getBean("classForSetA");
    }

    @Test
    //单例A和多例B
    public void fun3(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("ApplicationContext04.xml");
        //先创建单例A不会报错
        System.out.println(applicationContext.getBean("classForSingleA"));
        System.out.println(applicationContext.getBean("classForPrototypeB"));

        //先创建多例 B 会报错
//        System.out.println(applicationContext.getBean("classForPrototypeB"));
//        System.out.println(applicationContext.getBean("classForSingleA"));
    }

    @Test
    //验证三级缓存早期对象与初始化后的对象不一致报错
    public void fun4(){
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        applicationContext.register(CacheConfig.class);
        applicationContext.refresh();

        CacheA cacheA = applicationContext.getBean(CacheA.class);
        cacheA.fun1();
    }

    @Test
    //接受三级缓存早期对象与初始化后的对象不一致报错
    public void fun5(){
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();

        //创建一个BeanFactoryPostProcessor：BeanFactory后置处理器
        applicationContext.addBeanFactoryPostProcessor(beanFactory -> {
            if(beanFactory instanceof DefaultListableBeanFactory){
                //接受参数allowRawInjectionDespiteWrapping默认为FALSE
                ((DefaultListableBeanFactory) beanFactory).setAllowRawInjectionDespiteWrapping(true);
            }
        });

        applicationContext.register(CacheConfig.class);
        applicationContext.refresh();

        CacheA cacheA = applicationContext.getBean(CacheA.class);
        CacheB cacheB = applicationContext.getBean(CacheB.class);

        cacheA.fun1();
        cacheB.fun1();
    }
}
